#include "Scene.h"
#include "Object.h"
#include <iostream>
#include <unistd.h>
#include <algorithm>
#include <chrono>
#include <fstream>
int pace1,pace2;
Scene::Scene(Player &p,Shop & a,Scene &sc):p(p),a(a),sc(sc)
{
    for(int i = 0;i < MapSize;i++)
    {
        for(int j = 0;j < MapSize;j++)
        {
            Map[i][j] = "🎄";
        }
    }

    p.InitMonsters();
    // InitShop();
    p.Box->InitTreasureBoxes();
}

// void Scene::InitMonsters()
// {   
//     if(!Exits())
//     {
//         for (int i = 0; i < 5; ++i) {
//             auto [x, y] = generateUniqueCoordinates();
//             monsters.push_back(std::make_shared<Monster>(x, y, "哥布林", "🐵", 10, 2, 2, 100,100));
//         }

//         for (int i = 0; i < 3; ++i) {
//             auto [x, y] = generateUniqueCoordinates();

//             monsters.push_back(std::make_shared<Monster>(x, y, "骨头骑士", "💀", 10, 2, 2, 50,200));
//         }

//         for (int i = 0; i < 2; ++i) {
//             auto [x, y] = generateUniqueCoordinates();
//             monsters.push_back(std::make_shared<Monster>(x, y, "巨龙", "🐲", 10, 2, 2, 100,300));
//         }   
    
//         auto [x, y] = generateUniqueCoordinates();
//         monsters.push_back(std::make_shared<Monster>(x, y, "魔王", "👹", 200, 50, 40, 100,500));
//     }
//     else
//     {
//         loadMonsters();
//     }
//     // auto [x1, y1] = generateUniqueCoordinates();
//     // shops.push_back(shop(x1,y1,"商店","🏬"));
// }

void Scene::InitShop()
{   
    auto [x, y] = generateUniqueCoordinates();
    shops.push_back(Shop(x,y,"商店","🏬",p));
}

void Scene::show()
{   
    Clear();
    Map[p.GetY()][p.GetX()] = p.GetSymbol();
    Map[a.GetY()][a.GetX()] = a.GetSymbol();

    // Map 是 std::string Map[10][10];
    const int MAP_HEIGHT = 10;  // Map 的行数
    const int MAP_WIDTH = 10;   // Map 的列数

    // 创建 hasMonster 数组
    bool hasMonster[MAP_HEIGHT][MAP_WIDTH] = {false};  // 初始化所有元素为 false

    // 先处理怪物
    auto& monsters = p.GetMonster();
    for(auto& ite : monsters)
    {
        if(ite->GetHP() > 0)
        {
            Map[ite->GetY()][ite->GetX()] = ite->GetSymbol();
            hasMonster[ite->GetY()][ite->GetX()] = true;  // 标记这个位置有怪物
        }
    }

    // 然后处理宝箱
    auto& treasureBoxes = p.Box->GetTrea();
    for (auto& ite : treasureBoxes)
    {
        // 只有当该位置没有怪物时，才显示宝箱
        if (!hasMonster[ite->GetY()][ite->GetX()])
        {
            Map[ite->GetY()][ite->GetX()] = ite->GetSymbol();
        }
    }
    // auto& monsters = p.GetMonster();
    // for(auto& ite : monsters)
    // {   
    //     if(ite->GetHP() > 0)
    //     Map[ite->GetY()][ite->GetX()] = ite->GetSymbol();
    // }
    // // p.MonsterShow();
    // auto& treasureBoxes = p.Box->GetTrea();
    // for (auto& ite : treasureBoxes)
    // {   
    //     Map[ite->GetY()][ite->GetX()] = ite->GetSymbol();
    // }
    // std::cout.width(5);
    // std::left(std::cout); //左对齐
    for(int i = 0;i < MapSize;i++)
    {
        for(int j = 0;j < MapSize;j++)
        {
            std::cout<<Map[i][j]<<" ";
        }
        std::cout<<std::endl;
    }
}

void Scene::Clear()
{
    for(int i = 0;i < MapSize;i++)
    {
        for(int j = 0;j < MapSize;j++)
        {
            Map[i][j] = "🎄";
        }
    }
}

Monster* Scene::IsPosEqual()
{   
    auto& monsters = p.GetMonster();
    for(auto& ite : monsters)
    {
        if(ite->GetHP() > 0&&ite->GetX() == p.GetX() && ite->GetY() == p.GetY())
        {
            return ite.get();
        }
    }
    return nullptr;
}

bool Scene::ISPosEqual()
{
    if(a.GetX() == p.GetX() && a.GetY() == p.GetY())
    {
        return true;
    }
    return false;
}

TreasureBox *Scene::TIsPosEqual()
{   
    auto& treasureBoxes = p.Box->GetTrea();
    for (auto& ite : treasureBoxes) 
    {
        if (ite->GetX() == p.GetX() && ite->GetY() == p.GetY()) 
        {
            return ite.get();
        }
    }
    return nullptr;
}

void Scene::GetTreasureBox(TreasureBox *t)
{
    while(1)
    {   
        system("clear");
        t->Get();
        std::cout<<"恭喜获得"<<p.GetBag().GetName()<<std::endl;
        if(p.GetBag().GetName() == "Money")
        {
            p.GetBag().RemoveL();
        }
        // RemoveTreasureBoxes(t);
        sleep(1);
        break;
    }
}

void Scene::Fight(Monster *m)
{   
    while(1)
{   
    system("clear");
    p.show();
    m->show();
    std::cout<<"==========================================================\n";
    std::cout<<"请选择你的攻击模式:"<<std::endl;
    std::cout<<"1、普通攻击"<<std::endl;
    std::cout<<"2、暴击"<<std::endl;
    std::cout<<"3、逃跑"<<std::endl;
    std::cout<<"b、进入背包"<<std::endl;
    char c = 0;
    std::cin>>c;
    switch (c)
    {
    case 49:
    {
        Player2Monster(m);
        Monster2Player(m);
        break;
    }
    case 50:
    {
        Player2Monster(m,2,2);
        Monster2Player(m);
        break;
    }
    case 51:
    {   
        if(Escape())
        {   
            sleep(2);
            p.SetX(pace1);
            p.SetY(pace2);
            return;
        }
        Monster2Player(m);
        break;
    }
    case 'b':
    {
        std::cout << "进入背包:" << std::endl;
        p.GetBag().show();
        break;
    }
    default:
        break;
    }
    if(p.GetHP() <= 0)
    {
        printf("你失败了！游戏结束！\n");
        sleep(2);
        exit(0);
    }
    if(m->GetHP() <= 0)
    {
        printf("你战胜了|%s|\n",m->GetName().c_str());
        if(m->GetName() == "魔王")
        {
            std::cout<<"恭喜少侠，闯关成功！"<<std::endl;
            sleep(3);
            exit(-1);
        }
        p.SetExp(p.GetExp() + m->GetExp());
        p.Setmoney(p.Getmoney() + m->GetMoney());
        sleep(1);
        p.LevelUp();
        sleep(1);
        p.RefreshMonster(m);
        // RemoveMonster(m);
        return;
    }

    sleep(2); //让程序休眠
    }
}

void Scene::Player2Monster(Monster *m)
{
    int damage = p.GetAttack() - m->Getdefends();
    if(damage <= 0)
    {
        printf("我们未能击穿敌方装甲!\n");
    }
    else
    {
        std::cout<<"|"<<p.GetName()<<"|对|"<<m->GetName()<<"|发动普通攻击，造成|"<<damage<<"|点伤害"<<std::endl;
        m->SetHP(m->GetHP() - damage);
    }
    
}

void Scene::Player2Monster(Monster *m, int rata, int mutiple)
{
    srand(time(nullptr));
    int r = rand() % 2;
    if(r == 0)
    {
        printf("|%s|暴击失败!\n",p.GetName().c_str());
    }
    else
    {   
        int damage = mutiple*p.GetAttack() - m->Getdefends();
        printf("|%s|暴击成功！对|%s|造成双倍伤害！!\n",p.GetName().c_str(),m->GetName().c_str());
        if(damage <= 0)
        {
            printf("我们未能击穿敌方装甲!\n");
        }
        else
        {   
            printf("伤害值为|%d|\n",damage);
            m->SetHP(m->GetHP() - damage);
        }
    }
}

bool Scene::Escape()
{
    srand(time(nullptr));
    int rate = rand() % 3;
    if(rate == 2)
    {
        printf("|%s|逃跑成功!\n",p.GetName().c_str());
        return true;
    }
    else
    {   
        printf("|%s|逃跑失败!\n",p.GetName().c_str());
        // int damage = m->GetAttack() - p.Getdefends();
        // std::cout<<"|"<<m->GetName()<<"|对|"<<p.GetName()<<"|发动普通攻击，造成|"<<damage<<"|点伤害"<<std::endl;
        // p.SetHP(p.GetHP() - damage);
        return false;
    }
}

void Scene::Monster2Player(Monster *m)
{
    int damage = m->GetAttack() - p.Getdefends();
    if(damage <= 0)
    {
        printf("欸，没伤害!\n");
    }
    else
    {
        std::cout<<"|"<<m->GetName()<<"|对|"<<p.GetName()<<"|发动普通攻击，造成|"<<damage<<"|点伤害"<<std::endl;
        p.SetHP(p.GetHP() - damage);
    }
}

// void Scene::RefreshMonster(Monster *m)
// {   
//     // 将所有怪物的当前坐标添加到usedCoordinates集合中
//     usedCoordinates.clear();
//     auto& monsters = p.GetMonster();
//     for (const auto& monster : monsters) 
//     {
//         usedCoordinates.insert({monster->GetX(), monster->GetY()});
//     }

//     // 生成新的唯一坐标
//     auto [x, y] = generateUniqueCoordinates();
//     m->SetHP(m->GetMaxHp());  // 重置怪物的生命值
//     m->SetX(x);               // 设置怪物的新X坐标
//     m->SetY(y);               // 设置怪物的新Y坐标
// }

// void Scene::saveMonsters()
// {
//     std::string archiveDir = "存档";  // 使用 std::string 来表示存档目录

//     std::string username = global_username; 
// // 构建文件名，假设存档目录为 "Username/"，文件名为 "玩家数据.txt"
//     std::string filename = archiveDir + "/" + username + "/怪兽属性.txt";
//     std::ofstream outFile(filename);
//     if (!outFile) {
//         std::cerr << "无法打开文件进行写入: " << filename << std::endl;
//         return;
//     }
//     // std::cout << "monsters 类型: " << typeid(monsters).name() << ", 大小: " << monsters.size() << std::endl;
//     if(!monsters.empty())
//     {
//     for (const auto& monster : monsters) {
//         outFile << monster->GetX() << " "
//                 << monster->GetY() << " "
//                 << monster->GetName() << " "
//                 << monster->GetSymbol() << " "
//                 << monster->GetHP() << " "
//                 << monster->GetAttack() << " "
//                 << monster->Getdefends() << " "
//                 << monster->GetExp() << " "
//                 << monster->GetMoney() << std::endl;
//     }
//     }
//     outFile.close();
// }

// std::vector<Monster> Scene::loadMonsters()
// {   
//     std::string archiveDir = "存档";  // 使用 std::string 来表示存档目录

//     std::string username = global_username; 
// // 构建文件名，假设存档目录为 "Username/"，文件名为 "玩家数据.txt"
//     std::string filename = archiveDir + "/" + username + "/怪兽属性.txt";
//     std::vector<Monster> monsters;
//     std::ifstream inFile(filename);
//     if (!inFile) {
//         std::cerr << "无法打开文件进行读取: " << filename << std::endl;
//         return monsters;
//     }

//     while (inFile) {
//         Monster monster;
//         int x,y,hp,attack,defends,exp,money;
//         std::string name,symbol;
//         inFile >> x
//                >> y
//                >> name
//                >> symbol
//                >> hp
//                >> attack
//                >> defends
//                >> exp
//                >> money;
//         monster.SetX(x);  monster.SetY(y); monster.SetName(name); monster.SetSymbol(symbol); monster.SetHP(hp); monster.SetAttack(attack); monster.Setdefends(defends);
//         monster.SetExp(exp); monster.SetMoney(money);
//         // 检查是否成功读取一个怪物的数据
//         if (inFile) {
//             monsters.push_back(monster);
//         }
//     }

//     inFile.close();
//     return monsters;
// }

// bool Scene::Exits()
// {   
//     std::string archiveDir = "存档";  // 使用 std::string 来表示存档目录

//     std::string username = global_username; 
// // 构建文件名，假设存档目录为 "Username/"，文件名为 "玩家数据.txt"
//     std::string filename = archiveDir + "/" + username + "/怪兽属性.txt";
//     std::ifstream file(filename);
//     bool exists = file.is_open();
    
//     file.close(); // 显式关闭文件流
    
//     return exists;
// }

std::pair<int, int> Scene::generateUniqueCoordinates()
{   
    const std::pair<int, int> fixedCoordinate = {0, 2};
    int x, y;
    int attempts = 0;
    unsigned long long int seed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
        srand(seed); // 使用时间作为种子
    do {
        x = rand() % MapSize;
        y = rand() % MapSize;
        if (attempts > MapSize * MapSize) 
        {
            std::cerr << "Error: Unable to find unique coordinates after many attempts." << std::endl;
            exit(1); // 防止无限循环，退出程序
        }
    } while (usedCoordinates.count({x, y}) > 0); // 重复时重新生成
    usedCoordinates.insert({x, y});
    return {x, y};
}

void Scene::RemoveMonster(Monster *m)
{   
    auto& monsters = p.GetMonster();
     // 使用std::find_if查找并删除指定的怪物
    auto it = std::find_if(monsters.begin(), monsters.end(), [m](const std::shared_ptr<Monster>& monster) 
    {
        return monster.get() == m;
    });

    // 如果找到，则删除怪物
    if (it != monsters.end()) {
        monsters.erase(it);
    }
}

// void Scene::RemoveTreasureBoxes(TreasureBox *t)
// {
//     // 使用std::find_if查找并删除指定的怪物
//     auto it = std::find_if(treasureBoxes.begin(), treasureBoxes.end(), [t](const TreasureBox& treasureboxes) 
//     {
//         return &treasureboxes == t;
//     });

//     // 如果找到，则删除怪物
//     if (it != treasureBoxes.end()) {
//         treasureBoxes.erase(it);
//     }
// }

// void Scene::InitTreasureBoxes()
// {
//     for (int i = 0; i < 5; ++i) 
//     {
//         int x = std::rand() % MapSize;
//         int y = std::rand() % MapSize; 
//         do {
//             x = std::rand() % MapSize;
//             y = std::rand() % MapSize;
//         } while (isOverlap(treasureBoxes, x, y));
//         const std::string c = "宝箱";
//         const std::string d = "📦";
//          // 创建并添加宝箱
//         auto treasureBox = std::make_shared<TreasureBox>(x, y, c, d, a, p, sc);
//         treasureBoxes.push_back(treasureBox);
//     }
// }

// bool Scene::isOverlap(std::vector<std::shared_ptr<TreasureBox>> &treasureBoxes, int x, int y)
// {   
//      for (const auto& box : treasureBoxes) 
//      {
//         if (box->GetX() == x && box->GetY() == y) {
//             return true; // 发现重叠
//         }
//     }
//     return false;
// }

// void Scene::RemoveTreasureBox(int index)
// {
//     if (index >= 0 && index < treasureBoxes.size()) 
//     {
//         treasureBoxes.erase(treasureBoxes.begin() + index);
//     }
// }

// int Scene::GetTreasureBoxIndex(TreasureBox *t)
// {   
//     // auto & treasureBoxe = GetTrea();
//     for (int i = 0; i < treasureBoxes.size(); ++i) 
//     {
//         if (treasureBoxes[i].get() == t) 
//         {
//             return i;
//         }
//     }
//     return -1;  
// }
